/**
 * 
 */
package com.ly.hotel.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import com.ly.hotel.R;
import com.ly.hotel.common.MyApplication;

/**
 * @author jouson 2014-7-10
 */
public class WebInstaller {

	private Context context;
	private String apkurl; // 下载链接
	private String savePath; // 项目路径

	private ProgressDialog pBar;
	private DownLoadFileThread downLoadFileThread;
	private Handler handler;
	private String filename;
	private boolean silentInstall=false;
	public WebInstaller(Context context, String apkurl) {
		this.context = context;

		File dir = context.getDir("spadownload", Context.MODE_PRIVATE | Context.MODE_WORLD_READABLE
				| Context.MODE_WORLD_WRITEABLE);
		dir.mkdirs();
		this.apkurl = apkurl;
		this.savePath = dir.getAbsolutePath() + "/";
		handler = new Handler();

		filename = Math.abs(this.apkurl.hashCode()) + ".apk";
	}

	public WebInstaller(Context context, String apkurl, boolean silentInstall) {
		this.context = context;
		this.silentInstall = silentInstall;
		File dir = context.getDir("spadownload", Context.MODE_PRIVATE | Context.MODE_WORLD_READABLE
				| Context.MODE_WORLD_WRITEABLE);
		dir.mkdirs();
		this.apkurl = apkurl;
		this.savePath = dir.getAbsolutePath() + "/";
		handler = new Handler();

		filename = Math.abs(this.apkurl.hashCode()) + ".apk";
	}
	
	public WebInstaller(Context context, String apkurl, String savePath, String saveName) {
		this.context = context; 
/*		File dir = context.getDir("files",Context.MODE_PRIVATE | Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
		dir.mkdirs();
		*/
		this.apkurl = apkurl;
		this.savePath = savePath + "/";
		handler = new Handler();

		filename = saveName;
		
		getFilePermission(savePath);

	}
	
	public void downloadAndInstall() {

		pBar = new ProgressDialog(context);
		pBar.setTitle(R.string.down);
		pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		pBar.setCancelable(false);
		if(!silentInstall && !AppUtil.getVersionName(context,context.getPackageName()).startsWith("1.")){
			pBar.setMessage(context.getResources().getString(R.string.downing));
			pBar.setButton(ProgressDialog.BUTTON_NEGATIVE, context.getResources().getString(R.string.cancel),
					new OnClickListener() {
	
						public void onClick(DialogInterface dialog, int which) {
							pBar.cancel();
							if (downLoadFileThread != null) {
								downLoadFileThread.interrupt();
							}
						}
					});
/*			pBar.setButton(ProgressDialog.BUTTON_NEUTRAL, context.getResources().getString(R.string.background_download),
					new OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							pBar.cancel();
						}
					});*/
		}else{
			pBar.setMessage("升级安装中，请稍后...");
		}
		pBar.setProgress(100);
		pBar.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
		pBar.show();
		downLoadFileThread = new DownLoadFileThread(apkurl, savePath + this.filename, new DownloadCallback() {

			@Override
			public void onSuccess() {
				handler.post(new Runnable() {
					@Override
					public void run() {
						if(!AppUtil.getVersionName(context,context.getPackageName()).startsWith("1."))
						{
							pBar.cancel();
						}
						Toast.makeText(context, context.getResources().getString(R.string.download_complete),
								Toast.LENGTH_LONG).show();
						install(savePath + filename);
					}
				});
			}

			@Override
			public void onPrecessing(int written, long total) {
				int c = (int) ((long) written * 100 / total);
				pBar.setProgress(c);
			}

			@Override
			public void onFail(Throwable e) {
				e.printStackTrace();
				handler.post(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(context, context.getString(R.string.DownFailed), Toast.LENGTH_LONG).show();
					}
				});
				pBar.cancel();
			}

			@Override
			public void onCancel() {
				handler.post(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(context, context.getResources().getString(R.string.download_cancel),
								Toast.LENGTH_LONG).show();
					}
				});
			}
		});
		downLoadFileThread.start();
	}

	public static String execCommand(String... command) {
		Process process = null;
		InputStream errIs = null;
		InputStream inIs = null;
		String result = "";

		try {
			process = new ProcessBuilder().command(command).start();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int read = -1;
			errIs = process.getErrorStream();
			while ((read = errIs.read()) != -1) {
				baos.write(read);
			}
			inIs = process.getInputStream();
			while ((read = inIs.read()) != -1) {
				baos.write(read);
			}
			result = new String(baos.toByteArray());
			if (inIs != null)
				inIs.close();
			if (errIs != null)
				errIs.close();
			process.destroy();
		} catch (IOException e) {
			result = e.getMessage();
		}
		return result;
	}

	private void install(String fullfilepath) {
/*		PackageManager pm = this.context.getPackageManager();
        PackageInfo info = pm.getPackageArchiveInfo(fullfilepath, PackageManager.GET_ACTIVITIES);
        ApplicationInfo appInfo = null;
        String suid = null;
        if (info != null) {
            appInfo = info.applicationInfo;
            int uid = appInfo.uid;
            suid = info.sharedUserId;
            String packageName = appInfo.packageName;
            if(suid == null){
            	suid = "null";
            }
            Log.e("update", packageName + " =>> appInfo.uid = " + uid + ",info.sharedUserId = " +  suid);
        }
        */

		/*if(AppUtil.getVersionName(context,context.getPackageName()).startsWith("1.")){
			Log.i("installApk","静默安装：" + fullfilepath);
			getFilePermission(fullfilepath);
			String result = execCommand("pm", "install", "-r", fullfilepath);
			pBar.cancel();
			Toast.makeText(context, "安装结果:" + result, Toast.LENGTH_LONG).show();
		}else {
			if (!silentInstall || !MyApplication.canRunRootCommands) {
				System.out.println("安装:" + fullfilepath);
				getFilePermission(fullfilepath);
				Intent intent = new Intent();
				intent.setAction(Intent.ACTION_VIEW);
				intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				intent.setDataAndType(Uri.parse("file://" + fullfilepath), "application/vnd.android.package-archive");
				context.startActivity(intent);
			} else {
				*//********************************* 静默安装  -r是保留原有数据*****************************//*
				getFilePermission(fullfilepath);
				System.out.println("使用命令升级apk");
				String result = execCommand("pm", "install", "-r", fullfilepath);
				System.out.println("安装结果:" + result);
				Toast.makeText(context, "安装结果:" + result, Toast.LENGTH_LONG).show();
				*//****************************************************************************//*
			}
		}*/

		if (!silentInstall || !MyApplication.canRunRootCommands) {
			System.out.println("安装:" + fullfilepath);
			getFilePermission(fullfilepath);
			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_VIEW);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.setDataAndType(Uri.parse("file://" + fullfilepath), "application/vnd.android.package-archive");
			context.startActivity(intent);
		} else {
			/********************************* 静默安装  -r是保留原有数据*****************************/
			getFilePermission(fullfilepath);
			System.out.println("使用命令升级apk");
			String result = execCommand("pm", "install", "-r", fullfilepath);
			System.out.println("安装结果:" + result);
			Toast.makeText(context, "安装结果:" + result, Toast.LENGTH_LONG).show();
			/****************************************************************************/
		}
	}

	private void getFilePermission(String file) {
		ShellExecute ex = new ShellExecute();
		String[] cmd = { "chmod", "777", file };
		try {
			ex.execute(cmd, "/");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class DownLoadFileThread extends Thread {

		private String url;
		// 文件保存路径
		private String fullFilename;
		private DownloadCallback callback;

		public DownLoadFileThread(String url, String fullFilename, DownloadCallback callback) {
			Log.i("webInstall", url + " " + fullFilename);
			this.url = url;
			this.fullFilename = fullFilename;
			this.callback = callback;
		}

		public void run() {
			HttpClient client = new DefaultHttpClient();
			HttpGet get = new HttpGet(this.url);
			HttpResponse response;

			FileOutputStream outStream = null;
			try {
				response = client.execute(get);

				HttpEntity entity = response.getEntity();
				long length = entity.getContentLength();
				InputStream is = entity.getContent();
				File f = new File(fullFilename);
				f.getParentFile().mkdirs();
				if (is != null) {
					// outStream = context.openFileOutput(fullFilename,
					// Context.MODE_WORLD_READABLE);
					outStream = new FileOutputStream(new File(fullFilename));

					byte[] buf = new byte[1024];
					int ch = -1;
					int count = 0;
					while ((ch = is.read(buf)) != -1) {
						if (this.isInterrupted()) {
							callback.onCancel();
							return;
						}
						outStream.write(buf, 0, ch);
						count += ch;
						// Logger.i("已经写入" + count + "/" + length);
						if (count != 0) {
							callback.onPrecessing(count, length);
						}
					}
				}
				outStream.flush();
				callback.onSuccess();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
				callback.onFail(e);
			} catch (IOException e) {
				e.printStackTrace();
				callback.onFail(e);
			} finally {
				if (outStream != null) {
					try {
						outStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	interface DownloadCallback {
		public void onSuccess();
		public void onPrecessing(int written, long total);
		public void onFail(Throwable e);
		public void onCancel();
	}

	private class ShellExecute {
		/*
		 * args[0] : shell 命令 如"ls" 或"ls -1"; args[1] : 命令执行路径 如"/" ;
		 */
		public String execute(String[] cmmand, String directory) throws IOException {
			String result = "";
			try {
				ProcessBuilder builder = new ProcessBuilder(cmmand);
				if (directory != null)
					builder.directory(new File(directory));
				builder.redirectErrorStream(true);
				Process process = builder.start();
				// 得到命令执行后的结果
				InputStream is = process.getInputStream();
				byte[] buffer = new byte[1024];
				while (is.read(buffer) != -1) {
					result = result + new String(buffer);
				}
				is.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return result;
		}
	}
}
